package cn.huimin.httpClient;


import cn.huimin.httpClient.entity.HttpClientEntity;
import cn.huimin.httpClient.ex.URLEmptyException;
import cn.huimin.web.jwt.sign.SHA256Sign;
import cn.huimin.web.jwt.verify.Md5Verify;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.web.bind.annotation.RequestMethod;

import java.io.File;
import java.util.Date;
import java.util.Map;

/**
 * 基础功能的抽象实现
 */
public abstract class AbstractHttpClient implements IHttpClient {

    protected String responseData;
    protected HttpClientEntity client = new HttpClientEntity();
    protected String responseStatus;
    protected String encoding = "UTF-8";
    protected Integer socketTimeout = 20000;
    protected Integer connectTimeout = 20000;
    protected String uri;

    /**
     * 添加请求参数
     * @param name 请求参数key值
     * @param value 请求参数key对应的value
     * @return
     */
    @Override
    public IHttpClient addParam(String name, Object value) {
        client.addParam(name, value);
        return this;
    }

    /**
     * 添加请求头
     * @param name header的key值
     * @param value header的key值对应的value
     * @return
     */
    @Override
    public IHttpClient addHeader(String name, String value) {
        client.addHeader(name, value);
        return this;
    }

    /**
     * 添加请求文件参数
     * @param name 请求参数key值
     * @param path 请求文件参数对应的地址
     * @return
     */
    public IHttpClient addFileParam(String name, String path) {
        File file = new File(path);
        client.addParam(name, file);
        return this;
    }

    /**
     * 设置请求的URL和端口信息
     * @param url 请求的url
     * @param port 请求地址对应的端口
     * @return
     */
    public IHttpClient setUrl(String url, Long port) {
        client.setPort(port);
        return setUrl(url);
    }


    /**
     * 设置请求的URL
     * @param url 请求的url
     * @return
     */
    public IHttpClient setUrl(String url) {
        client.setUrl(url);
        return this;
    }

    /**
     * 设置请求的字符集
     * @param encoding
     */
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    /**
     * 设置socket超时时间
     * @param socketTimeout
     */
    public void setSocketTimeout(Integer socketTimeout) {
        this.socketTimeout = socketTimeout;
    }

    /**
     * 设置连接超时时间
     * @param connectTimeout
     */
    public void setConnectTimeout(Integer connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    /**
     * 获取请求响应码
     * @return
     */
    public String getResponseStatus() {
        return responseStatus;
    }


    @Override
    public void encrypt256Sign(Map<String, String> paramMap) {

        String key = "~*DaxW*$ETSCwPqTWmKe9j*u(BV4it5N";
        // 生成签名
        paramMap = SHA256Sign.sign(paramMap, key);
        for (String parKey :paramMap.keySet()){
            this.addParam(parKey, paramMap.get(parKey));
        }
    }

    public void encryptMicroSign() throws URLEmptyException {
        String nonce = RandomStringUtils.randomAlphanumeric(20);
        String timestamp = String.valueOf(new Date().getTime()).substring(0,10);
        String host = "cn.huimin100.hmsp";

        String sign ="";
        if(this.getMethodType().equals(RequestMethod.GET)||
                this.getMethodType().equals(RequestMethod.DELETE)
                ){

            String queryString = "";
            String requestUrl = this.client.getRequestUrl().toString();
            if(requestUrl.indexOf("?")>0){
                queryString =requestUrl.substring(requestUrl.indexOf("?"));
            }
            System.out.println(queryString);
            sign = Md5Verify.md5sum(nonce+timestamp+ this.uri + "?" + queryString +'{' + host + '}');
        }else{

            JSONObject paramJson = new JSONObject();
            for (Map.Entry<String, Object> paramMap: this.client.getParams().entrySet()) {
                paramJson.put(paramMap.getKey(),paramMap.getValue());
            }
            sign = Md5Verify.md5sum(nonce+timestamp+paramJson.toJSONString()+'{' + host + '}');
        }

        System.out.println(sign);
        this.addHeader("X_Timestamp",timestamp);
        this.addHeader("X_Nonce",String.valueOf(nonce));
        this.addHeader("X_Sign",sign);
    }

    @Override
    public void setUri(String uri) {
        this.uri = uri;
    }
}
